package com.loveprogrammer.netty.simple;

import com.loveprogrammer.codec.MessageDecoder;
import com.loveprogrammer.codec.MessageEncoder;
import com.loveprogrammer.command.server.ServerLoginOrRegisterTag;
import com.loveprogrammer.command.server.ServerTopic;
import com.loveprogrammer.constants.ConstantValue;
import com.loveprogrammer.handler.TcpMessageStringHandler;
import com.loveprogrammer.network.NetworkClientListener;
import com.loveprogrammer.pojo.StringMessage;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Optional;

/**
 * @ClassName SocketClient
 * @Description TODO
 * @Author admin
 * @Date 2024/1/29 17:43
 * @Version 1.0
 */
public class SocketClient {

    private static final Logger logger = LoggerFactory.getLogger(SocketClient.class);
    private static final String IP = "127.0.0.1";
    private static final int PORT = 8088;

    private static EventLoopGroup group = new NioEventLoopGroup();

    public static void run(String ip,Integer port) throws InterruptedException {
        ip = Optional.ofNullable(ip).orElse(IP);
        port = Optional.ofNullable(port).orElse(PORT);

        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group);
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535));
        bootstrap.handler(new ChannelInitializer() {
            @Override
            protected void initChannel(Channel ch) {
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast("encoder", new MessageEncoder());
                pipeline.addLast("decoder", new MessageDecoder(ConstantValue.MESSAGE_CODEC_MAX_FRAME_LENGTH,
                        ConstantValue.MESSAGE_CODEC_LENGTH_FIELD_LENGTH, ConstantValue.MESSAGE_CODEC_LENGTH_FIELD_OFFSET,
                        ConstantValue.MESSAGE_CODEC_LENGTH_ADJUSTMENT, ConstantValue.MESSAGE_CODEC_INITIAL_BYTES_TO_STRIP,
                        false));

                pipeline.addLast(new TcpMessageStringHandler(NetworkClientListener.getInstance()));
            }
        });

        // 连接服务器 - 打个招呼
        ChannelFuture channelFuture = bootstrap.connect(ip, port).sync();
        StringMessage msg = StringMessage.create(ServerTopic.TOPIC_HELLO, ServerLoginOrRegisterTag.TAG_HELLO_HI);
        msg.setStatusCode(200);
        msg.setBody("你好，我是eric");
        channelFuture.channel().writeAndFlush(msg);
        logger.info("向服务器发送消息 {}",msg);
        channelFuture.channel().closeFuture().sync();

    }

    public static void main(String[] args) {
        logger.info("开始连接Socket服务器...");
        try {
            if(args.length > 2){
                run(args[0], Integer.valueOf(args[1]));
            }
            else {
                run(null,null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully();
        }
    }


}
